{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在我之前的博客中我们介绍了文本的多分类的方法,我们还尝试了各种分类模型,比如朴素贝叶斯、逻辑回归、支持向量机和随机森林等并且都取得了非常不错的效果。今天我们使用深度学习中的LSTM（Long Short-Term Memory）长短期记忆网络，它是一种时间循环神经网络，适合于处理和预测时间序列中间隔和延迟相对较长的重要事件。\n",
    "LSTM 已经在科技领域有了多种应用。基于 LSTM 的系统可以学习翻译语言、控制机器人、图像分析、文档摘要、语音识别图像识别、手写识别、控制聊天机器人、预测疾病、点击率和股票、合成音乐等等任务。今天我们用它来实现一下文本多分类，相信会取得较好的效果。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 数据\n",
    "\n",
    "我们的数据来自于互联网，你可以在这里下载,数据中包含了10 个类别（书籍、平板、手机、水果、洗发水、热水器、蒙牛、衣服、计算机、酒店），共 6 万多条评论数据 首先查看一下我们的数据，这些数据都是来自于电商网站的用户评价数据,我们想要把不同评价数据分到不同的分类中去,且每条数据只能对应10个类中的一个类。\n",
    "\n",
    "数据下载地址:https://github.com/SophonPlus/ChineseNlpCorpus/blob/master/datasets/online_shopping_10_cats/intro.ipynb\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/zheming2009/anaconda3/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
      "  from ._conv import register_converters as _register_converters\n",
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "#coding=utf-8\n",
    "%matplotlib inline\n",
    "import pandas as pd\n",
    "import matplotlib\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "plt.rcParams['font.sans-serif'] = ['SimHei']  \n",
    "plt.rcParams['axes.unicode_minus'] = False \n",
    "from keras.preprocessing.text import Tokenizer\n",
    "from keras.preprocessing.sequence import pad_sequences\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dense, Embedding, LSTM, SpatialDropout1D\n",
    "from sklearn.model_selection import train_test_split\n",
    "from keras.utils.np_utils import to_categorical\n",
    "from keras.callbacks import EarlyStopping\n",
    "from keras.layers import Dropout\n",
    "import jieba as jb\n",
    "import re"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "数据总量: 62774 .\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>cat</th>\n",
       "      <th>review</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>21417</th>\n",
       "      <td>水果</td>\n",
       "      <td>一个字烂，两个字太烂，三个字非常烂，好差的苹果，第一次在京东上买到这么差的东西，商家太不负责...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24902</th>\n",
       "      <td>水果</td>\n",
       "      <td>第一买鲜货 结果很失望 有烂的 个头也很小</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>26050</th>\n",
       "      <td>水果</td>\n",
       "      <td>图片仅供参考～颜色并没有图片那么好看，苹果也很小，更不能常温储存，也不新鲜?</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5680</th>\n",
       "      <td>平板</td>\n",
       "      <td>外观不错，只是用久了会不会慢？</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24125</th>\n",
       "      <td>水果</td>\n",
       "      <td>这是放了多长时间的水果啊，长霉的长霉，烂的烂，流脓滴水，第一次京东买水果，还自营，就这品质？</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10931</th>\n",
       "      <td>平板</td>\n",
       "      <td>不是很满意的一次购物 声音还特小 送的乐视会员 根本就兑换不了会员 一星都不想给</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8806</th>\n",
       "      <td>平板</td>\n",
       "      <td>优点，很好用，屏幕大，带机时间长。缺点，只送了一个屏幕保护膜，套子都没送一个，还有我买的是3...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>37303</th>\n",
       "      <td>蒙牛</td>\n",
       "      <td>个人比较喜欢蒙牛的新包装</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4559</th>\n",
       "      <td>平板</td>\n",
       "      <td>感觉还可以，没有磨损，应该是新机，用一段时间再评论。</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>52941</th>\n",
       "      <td>酒店</td>\n",
       "      <td>所在地应该是徐汇比较好的地段，很幽静，旁边就是爱菊小学，出门往右走到路口有超市和水果店，好像...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      cat                                             review\n",
       "21417  水果  一个字烂，两个字太烂，三个字非常烂，好差的苹果，第一次在京东上买到这么差的东西，商家太不负责...\n",
       "24902  水果                              第一买鲜货 结果很失望 有烂的 个头也很小\n",
       "26050  水果             图片仅供参考～颜色并没有图片那么好看，苹果也很小，更不能常温储存，也不新鲜?\n",
       "5680   平板                                    外观不错，只是用久了会不会慢？\n",
       "24125  水果     这是放了多长时间的水果啊，长霉的长霉，烂的烂，流脓滴水，第一次京东买水果，还自营，就这品质？\n",
       "10931  平板           不是很满意的一次购物 声音还特小 送的乐视会员 根本就兑换不了会员 一星都不想给\n",
       "8806   平板  优点，很好用，屏幕大，带机时间长。缺点，只送了一个屏幕保护膜，套子都没送一个，还有我买的是3...\n",
       "37303  蒙牛                                       个人比较喜欢蒙牛的新包装\n",
       "4559   平板                         感觉还可以，没有磨损，应该是新机，用一段时间再评论。\n",
       "52941  酒店  所在地应该是徐汇比较好的地段，很幽静，旁边就是爱菊小学，出门往右走到路口有超市和水果店，好像..."
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv('./data/online_shopping_10_cats.csv')\n",
    "df=df[['cat','review']]\n",
    "print(\"数据总量: %d .\" % len(df))\n",
    "df.sample(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "在 cat 列中总共有 0 个空值.\n",
      "在 review 列中总共有 1 个空值.\n"
     ]
    }
   ],
   "source": [
    "print(\"在 cat 列中总共有 %d 个空值.\" % df['cat'].isnull().sum())\n",
    "print(\"在 review 列中总共有 %d 个空值.\" % df['review'].isnull().sum())\n",
    "df[df.isnull().values==True]\n",
    "df = df[pd.notnull(df['review'])]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>cat</th>\n",
       "      <th>count</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>衣服</td>\n",
       "      <td>10000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>水果</td>\n",
       "      <td>10000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>洗发水</td>\n",
       "      <td>10000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>平板</td>\n",
       "      <td>10000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>酒店</td>\n",
       "      <td>10000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>计算机</td>\n",
       "      <td>3992</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>书籍</td>\n",
       "      <td>3851</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>手机</td>\n",
       "      <td>2323</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>蒙牛</td>\n",
       "      <td>2033</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>热水器</td>\n",
       "      <td>574</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   cat  count\n",
       "0   衣服  10000\n",
       "1   水果  10000\n",
       "2  洗发水  10000\n",
       "3   平板  10000\n",
       "4   酒店  10000\n",
       "5  计算机   3992\n",
       "6   书籍   3851\n",
       "7   手机   2323\n",
       "8   蒙牛   2033\n",
       "9  热水器    574"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d = {'cat':df['cat'].value_counts().index, 'count': df['cat'].value_counts()}\n",
    "df_cat = pd.DataFrame(data=d).reset_index(drop=True)\n",
    "df_cat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5,0,'类目')"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f7ba81def60>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df_cat.plot(x='cat', y='count', kind='bar', legend=False,  figsize=(8, 5))\n",
    "plt.title(\"类目分布\")\n",
    "plt.ylabel('数量', fontsize=18)\n",
    "plt.xlabel('类目', fontsize=18)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 数据预处理\n",
    "\n",
    " 接下来我们要将cat类转换成id，这样便于以后的分类模型的训练。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>cat</th>\n",
       "      <th>review</th>\n",
       "      <th>cat_id</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>5289</th>\n",
       "      <td>平板</td>\n",
       "      <td>质量一般，用电量太大了，不好用？</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8917</th>\n",
       "      <td>平板</td>\n",
       "      <td>打电话时声音有噪音也没手电筒没耳机冲电也好慢</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11888</th>\n",
       "      <td>平板</td>\n",
       "      <td>没有说的那么好，内存只有10G很卡</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10101</th>\n",
       "      <td>平板</td>\n",
       "      <td>帮朋友给他们公司买的值班手机，手机电池有问题，因为收到货后刚刚充满电，很快就没电了，只能用两...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2415</th>\n",
       "      <td>书籍</td>\n",
       "      <td>以上的评论太好,让我有购买的冲动,但我看过后,还没有&lt;不生病的智慧&gt;好呢</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25648</th>\n",
       "      <td>水果</td>\n",
       "      <td>难得在京东上买一次生鲜，太失望了。火龙果一点不新鲜，一股霉味，以后再也不会买了</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18268</th>\n",
       "      <td>水果</td>\n",
       "      <td>从京东自营水果区抢购了一瓶新鲜水果，苹果、丑柑、进口黄猕猴桃，家人都爱吃！京东价格便宜质量好...</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7226</th>\n",
       "      <td>平板</td>\n",
       "      <td>手机很好 很大气 用起来运行速度也很快</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>62299</th>\n",
       "      <td>酒店</td>\n",
       "      <td>中午1点入住，到达房间门口却发现两张房卡均无法打开门锁，叫来楼层服务员打开后承诺马上把好的房...</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21428</th>\n",
       "      <td>水果</td>\n",
       "      <td>垃圾，收到后隔天就全烂了，一个都没吃上</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      cat                                             review  cat_id\n",
       "5289   平板                                   质量一般，用电量太大了，不好用？       1\n",
       "8917   平板                             打电话时声音有噪音也没手电筒没耳机冲电也好慢       1\n",
       "11888  平板                                  没有说的那么好，内存只有10G很卡       1\n",
       "10101  平板  帮朋友给他们公司买的值班手机，手机电池有问题，因为收到货后刚刚充满电，很快就没电了，只能用两...       1\n",
       "2415   书籍               以上的评论太好,让我有购买的冲动,但我看过后,还没有<不生病的智慧>好呢       0\n",
       "25648  水果            难得在京东上买一次生鲜，太失望了。火龙果一点不新鲜，一股霉味，以后再也不会买了       3\n",
       "18268  水果  从京东自营水果区抢购了一瓶新鲜水果，苹果、丑柑、进口黄猕猴桃，家人都爱吃！京东价格便宜质量好...       3\n",
       "7226   平板                                手机很好 很大气 用起来运行速度也很快       1\n",
       "62299  酒店  中午1点入住，到达房间门口却发现两张房卡均无法打开门锁，叫来楼层服务员打开后承诺马上把好的房...       9\n",
       "21428  水果                                垃圾，收到后隔天就全烂了，一个都没吃上       3"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['cat_id'] = df['cat'].factorize()[0]\n",
    "cat_id_df = df[['cat', 'cat_id']].drop_duplicates().sort_values('cat_id').reset_index(drop=True)\n",
    "cat_to_id = dict(cat_id_df.values)\n",
    "id_to_cat = dict(cat_id_df[['cat_id', 'cat']].values)\n",
    "df.sample(10)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>cat</th>\n",
       "      <th>cat_id</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>书籍</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>平板</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>手机</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>水果</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>洗发水</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>热水器</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>蒙牛</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>衣服</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>计算机</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>酒店</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   cat  cat_id\n",
       "0   书籍       0\n",
       "1   平板       1\n",
       "2   手机       2\n",
       "3   水果       3\n",
       "4  洗发水       4\n",
       "5  热水器       5\n",
       "6   蒙牛       6\n",
       "7   衣服       7\n",
       "8  计算机       8\n",
       "9   酒店       9"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cat_id_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们将cat转换成了Id(0到9),由于我们的评价内容都是中文,所以要对中文进行一些预处理工作,这包括删除文本中的标点符号,特殊符号,还要删除一些无意义的常用词(stopword),因为这些词和符号对系统分析预测文本的内容没有任何帮助,反而会增加计算的复杂度和增加系统开销,所有在使用这些文本数据之前必须要将它们清理干净。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "#定义删除除字母,数字，汉字以外的所有符号的函数\n",
    "def remove_punctuation(line):\n",
    "    line = str(line)\n",
    "    if line.strip()=='':\n",
    "        return ''\n",
    "    rule = re.compile(u\"[^a-zA-Z0-9\\u4E00-\\u9FA5]\")\n",
    "    line = rule.sub('',line)\n",
    "    return line\n",
    " \n",
    "def stopwordslist(filepath):  \n",
    "    stopwords = [line.strip() for line in open(filepath, 'r', encoding='utf-8').readlines()]  \n",
    "    return stopwords  \n",
    "\n",
    "#加载停用词\n",
    "stopwords = stopwordslist(\"./data/chineseStopWords.txt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "中文停用词包含了很多日常使用频率很高的常用词,如 吧，吗，呢，啥等一些感叹词等,这些高频常用词无法反应出文本的主要意思,所以要被过滤掉。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>cat</th>\n",
       "      <th>review</th>\n",
       "      <th>cat_id</th>\n",
       "      <th>clean_review</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>22088</th>\n",
       "      <td>水果</td>\n",
       "      <td>买回去几个都是坏的，当时没有看收货的时候应该装的时候就已经发霉了</td>\n",
       "      <td>3</td>\n",
       "      <td>买回去几个都是坏的当时没有看收货的时候应该装的时候就已经发霉了</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>62764</th>\n",
       "      <td>酒店</td>\n",
       "      <td>非常一般的酒店，房里设施很旧，房间送餐竟然要加多50%的送餐费。总之找不到好的方面来说，有其...</td>\n",
       "      <td>9</td>\n",
       "      <td>非常一般的酒店房里设施很旧房间送餐竟然要加多50的送餐费总之找不到好的方面来说有其他选择就不要去了</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>61015</th>\n",
       "      <td>酒店</td>\n",
       "      <td>位置不错，赶飞机很方便，有机场至宾馆互通大吧，司机根不错，赞一个，就是反复飞机飞过声音很大…</td>\n",
       "      <td>9</td>\n",
       "      <td>位置不错赶飞机很方便有机场至宾馆互通大吧司机根不错赞一个就是反复飞机飞过声音很大</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28147</th>\n",
       "      <td>洗发水</td>\n",
       "      <td>物流速度很给力，两大瓶三小瓶，用起来也很不错，</td>\n",
       "      <td>4</td>\n",
       "      <td>物流速度很给力两大瓶三小瓶用起来也很不错</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>47465</th>\n",
       "      <td>衣服</td>\n",
       "      <td>商品是拼接品。</td>\n",
       "      <td>7</td>\n",
       "      <td>商品是拼接品</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>32590</th>\n",
       "      <td>洗发水</td>\n",
       "      <td>明明下单了两套礼盒，结果今天只送货送到了一套？！是快递人员的疏忽还是厂家的失误？！还是说这就...</td>\n",
       "      <td>4</td>\n",
       "      <td>明明下单了两套礼盒结果今天只送货送到了一套是快递人员的疏忽还是厂家的失误还是说这就是趁双十一...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10618</th>\n",
       "      <td>平板</td>\n",
       "      <td>手机充满状态下，待机无故发热耗电，几小时没电关机了，本来是当备用机的如今待机都不行服了！问客...</td>\n",
       "      <td>1</td>\n",
       "      <td>手机充满状态下待机无故发热耗电几小时没电关机了本来是当备用机的如今待机都不行服了问客服说后台...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>53540</th>\n",
       "      <td>酒店</td>\n",
       "      <td>房间感觉很上海化，结构紧凑，服务态度尚可，大厅也不错，是个标准的四星酒店。只是周边环境不是特...</td>\n",
       "      <td>9</td>\n",
       "      <td>房间感觉很上海化结构紧凑服务态度尚可大厅也不错是个标准的四星酒店只是周边环境不是特别的优雅如...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5409</th>\n",
       "      <td>平板</td>\n",
       "      <td>买来降价了。。。。买给老人听戏用的。老人很满意。就是内存小。价钱在这了。</td>\n",
       "      <td>1</td>\n",
       "      <td>买来降价了买给老人听戏用的老人很满意就是内存小价钱在这了</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12843</th>\n",
       "      <td>平板</td>\n",
       "      <td>不值这个价钱，是别人退货的产品，很明显是拆封过的，很不爽的一次购物</td>\n",
       "      <td>1</td>\n",
       "      <td>不值这个价钱是别人退货的产品很明显是拆封过的很不爽的一次购物</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       cat                                             review  cat_id  \\\n",
       "22088   水果                   买回去几个都是坏的，当时没有看收货的时候应该装的时候就已经发霉了       3   \n",
       "62764   酒店  非常一般的酒店，房里设施很旧，房间送餐竟然要加多50%的送餐费。总之找不到好的方面来说，有其...       9   \n",
       "61015   酒店     位置不错，赶飞机很方便，有机场至宾馆互通大吧，司机根不错，赞一个，就是反复飞机飞过声音很大…       9   \n",
       "28147  洗发水                            物流速度很给力，两大瓶三小瓶，用起来也很不错，       4   \n",
       "47465   衣服                                            商品是拼接品。       7   \n",
       "32590  洗发水  明明下单了两套礼盒，结果今天只送货送到了一套？！是快递人员的疏忽还是厂家的失误？！还是说这就...       4   \n",
       "10618   平板  手机充满状态下，待机无故发热耗电，几小时没电关机了，本来是当备用机的如今待机都不行服了！问客...       1   \n",
       "53540   酒店  房间感觉很上海化，结构紧凑，服务态度尚可，大厅也不错，是个标准的四星酒店。只是周边环境不是特...       9   \n",
       "5409    平板               买来降价了。。。。买给老人听戏用的。老人很满意。就是内存小。价钱在这了。       1   \n",
       "12843   平板                  不值这个价钱，是别人退货的产品，很明显是拆封过的，很不爽的一次购物       1   \n",
       "\n",
       "                                            clean_review  \n",
       "22088                    买回去几个都是坏的当时没有看收货的时候应该装的时候就已经发霉了  \n",
       "62764  非常一般的酒店房里设施很旧房间送餐竟然要加多50的送餐费总之找不到好的方面来说有其他选择就不要去了  \n",
       "61015           位置不错赶飞机很方便有机场至宾馆互通大吧司机根不错赞一个就是反复飞机飞过声音很大  \n",
       "28147                               物流速度很给力两大瓶三小瓶用起来也很不错  \n",
       "47465                                             商品是拼接品  \n",
       "32590  明明下单了两套礼盒结果今天只送货送到了一套是快递人员的疏忽还是厂家的失误还是说这就是趁双十一...  \n",
       "10618  手机充满状态下待机无故发热耗电几小时没电关机了本来是当备用机的如今待机都不行服了问客服说后台...  \n",
       "53540  房间感觉很上海化结构紧凑服务态度尚可大厅也不错是个标准的四星酒店只是周边环境不是特别的优雅如...  \n",
       "5409                        买来降价了买给老人听戏用的老人很满意就是内存小价钱在这了  \n",
       "12843                     不值这个价钱是别人退货的产品很明显是拆封过的很不爽的一次购物  "
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#删除除字母,数字，汉字以外的所有符号\n",
    "df['clean_review'] = df['review'].apply(remove_punctuation)\n",
    "df.sample(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们过滤掉了review中的标点符号和一些特殊符号，并生成了一个新的字段 clean_review。接下来我们要在clean_review的基础上进行分词,把每个评论内容分成由空格隔开的一个一个单独的词语。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Building prefix dict from the default dictionary ...\n",
      "Loading model from cache /tmp/jieba.cache\n",
      "Loading model cost 0.876 seconds.\n",
      "Prefix dict has been built succesfully.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>cat</th>\n",
       "      <th>review</th>\n",
       "      <th>cat_id</th>\n",
       "      <th>clean_review</th>\n",
       "      <th>cut_review</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>书籍</td>\n",
       "      <td>﻿做父母一定要有刘墉这样的心态，不断地学习，不断地进步，不断地给自己补充新鲜血液，让自己保持...</td>\n",
       "      <td>0</td>\n",
       "      <td>做父母一定要有刘墉这样的心态不断地学习不断地进步不断地给自己补充新鲜血液让自己保持一颗年轻的...</td>\n",
       "      <td>做 父母 一定 刘墉 心态 不断 学习 不断 进步 不断 补充 新鲜血液 保持 一颗 年轻 ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>书籍</td>\n",
       "      <td>作者真有英国人严谨的风格，提出观点、进行论述论证，尽管本人对物理学了解不深，但是仍然能感受到...</td>\n",
       "      <td>0</td>\n",
       "      <td>作者真有英国人严谨的风格提出观点进行论述论证尽管本人对物理学了解不深但是仍然能感受到真理的火...</td>\n",
       "      <td>作者 真有 英国人 严谨 风格 提出 观点 进行 论述 论证 物理学 了解 不深 仍然 感受...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>书籍</td>\n",
       "      <td>作者长篇大论借用详细报告数据处理工作和计算结果支持其新观点。为什么荷兰曾经县有欧洲最高的生产...</td>\n",
       "      <td>0</td>\n",
       "      <td>作者长篇大论借用详细报告数据处理工作和计算结果支持其新观点为什么荷兰曾经县有欧洲最高的生产率...</td>\n",
       "      <td>作者 长篇大论 借用 详细 报告 数据处理 工作 计算结果 支持 其新 观点 荷兰 曾经 县...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>书籍</td>\n",
       "      <td>作者在战几时之前用了＂拥抱＂令人叫绝．日本如果没有战败，就有会有美军的占领，没胡官僚主义的延...</td>\n",
       "      <td>0</td>\n",
       "      <td>作者在战几时之前用了拥抱令人叫绝日本如果没有战败就有会有美军的占领没胡官僚主义的延续没有战后...</td>\n",
       "      <td>作者 战 之前 拥抱 令人 叫绝 日本 没有 战败 会 美军 占领 没胡 官僚主义 延续 没...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>书籍</td>\n",
       "      <td>作者在少年时即喜阅读，能看出他精读了无数经典，因而他有一个庞大的内心世界。他的作品最难能可贵...</td>\n",
       "      <td>0</td>\n",
       "      <td>作者在少年时即喜阅读能看出他精读了无数经典因而他有一个庞大的内心世界他的作品最难能可贵的有两...</td>\n",
       "      <td>作者 少年 时即 喜 阅读 看出 精读 无数 经典 一个 庞大 内心世界 作品 难能可贵 两...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  cat                                             review  cat_id  \\\n",
       "0  书籍  ﻿做父母一定要有刘墉这样的心态，不断地学习，不断地进步，不断地给自己补充新鲜血液，让自己保持...       0   \n",
       "1  书籍  作者真有英国人严谨的风格，提出观点、进行论述论证，尽管本人对物理学了解不深，但是仍然能感受到...       0   \n",
       "2  书籍  作者长篇大论借用详细报告数据处理工作和计算结果支持其新观点。为什么荷兰曾经县有欧洲最高的生产...       0   \n",
       "3  书籍  作者在战几时之前用了＂拥抱＂令人叫绝．日本如果没有战败，就有会有美军的占领，没胡官僚主义的延...       0   \n",
       "4  书籍  作者在少年时即喜阅读，能看出他精读了无数经典，因而他有一个庞大的内心世界。他的作品最难能可贵...       0   \n",
       "\n",
       "                                        clean_review  \\\n",
       "0  做父母一定要有刘墉这样的心态不断地学习不断地进步不断地给自己补充新鲜血液让自己保持一颗年轻的...   \n",
       "1  作者真有英国人严谨的风格提出观点进行论述论证尽管本人对物理学了解不深但是仍然能感受到真理的火...   \n",
       "2  作者长篇大论借用详细报告数据处理工作和计算结果支持其新观点为什么荷兰曾经县有欧洲最高的生产率...   \n",
       "3  作者在战几时之前用了拥抱令人叫绝日本如果没有战败就有会有美军的占领没胡官僚主义的延续没有战后...   \n",
       "4  作者在少年时即喜阅读能看出他精读了无数经典因而他有一个庞大的内心世界他的作品最难能可贵的有两...   \n",
       "\n",
       "                                          cut_review  \n",
       "0  做 父母 一定 刘墉 心态 不断 学习 不断 进步 不断 补充 新鲜血液 保持 一颗 年轻 ...  \n",
       "1  作者 真有 英国人 严谨 风格 提出 观点 进行 论述 论证 物理学 了解 不深 仍然 感受...  \n",
       "2  作者 长篇大论 借用 详细 报告 数据处理 工作 计算结果 支持 其新 观点 荷兰 曾经 县...  \n",
       "3  作者 战 之前 拥抱 令人 叫绝 日本 没有 战败 会 美军 占领 没胡 官僚主义 延续 没...  \n",
       "4  作者 少年 时即 喜 阅读 看出 精读 无数 经典 一个 庞大 内心世界 作品 难能可贵 两...  "
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#分词，并过滤停用词\n",
    "df['cut_review'] = df['clean_review'].apply(lambda x: \" \".join([w for w in list(jb.cut(x)) if w not in stopwords]))\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# LSTM建模 \n",
    "\n",
    "数据预处理完成以后，接下来我们要开始进行LSTM的建模工作：\n",
    "\n",
    "* 我们要将cut_review数据进行向量化处理,我们要将每条cut_review转换成一个整数序列的向量\n",
    "* 设置最频繁使用的50000个词\n",
    "* 设置每条 cut_review最大的词语数为250个(超过的将会被截去,不足的将会被补0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "共有 70364 个不相同的词语.\n"
     ]
    }
   ],
   "source": [
    "# 设置最频繁使用的50000个词(在texts_to_matrix是会取前MAX_NB_WORDS,会取前MAX_NB_WORDS列)\n",
    "MAX_NB_WORDS = 50000\n",
    "# 每条cut_review最大的长度\n",
    "MAX_SEQUENCE_LENGTH = 250\n",
    "# 设置Embeddingceng层的维度\n",
    "EMBEDDING_DIM = 100\n",
    "\n",
    "tokenizer = Tokenizer(num_words=MAX_NB_WORDS, filters='!\"#$%&()*+,-./:;<=>?@[\\]^_`{|}~', lower=True)\n",
    "tokenizer.fit_on_texts(df['cut_review'].values)\n",
    "word_index = tokenizer.word_index\n",
    "print('共有 %s 个不相同的词语.' % len(word_index))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "训练和测试的数据集都准备好以后,接下来我们要定义一个LSTM的序列模型:  \n",
    "\n",
    "* 模型的第一次是嵌入层(Embedding)，它使用长度为100的向量来表示每一个词语\n",
    "* SpatialDropout1D层在训练中每次更新时， 将输入单元的按比率随机设置为 0， 这有助于防止过拟合\n",
    "* LSTM层包含100个记忆单元\n",
    "* 输出层为包含10个分类的全连接层\n",
    "* 由于是多分类，所以激活函数设置为'softmax'\n",
    "* 由于是多分类, 所以损失函数为分类交叉熵categorical_crossentropy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(62773, 250)\n",
      "(62773, 10)\n"
     ]
    }
   ],
   "source": [
    "X = tokenizer.texts_to_sequences(df['cut_review'].values)\n",
    "#填充X,让X的各个列的长度统一\n",
    "X = pad_sequences(X, maxlen=MAX_SEQUENCE_LENGTH)\n",
    "\n",
    "#多类标签的onehot展开\n",
    "Y = pd.get_dummies(df['cat_id']).values\n",
    "\n",
    "print(X.shape)\n",
    "print(Y.shape)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(56495, 250) (56495, 10)\n",
      "(6278, 250) (6278, 10)\n"
     ]
    }
   ],
   "source": [
    "#拆分训练集和测试集\n",
    "X_train, X_test, Y_train, Y_test = train_test_split(X,Y, test_size = 0.10, random_state = 42)\n",
    "print(X_train.shape,Y_train.shape)\n",
    "print(X_test.shape,Y_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "embedding_1 (Embedding)      (None, 250, 100)          5000000   \n",
      "_________________________________________________________________\n",
      "spatial_dropout1d_1 (Spatial (None, 250, 100)          0         \n",
      "_________________________________________________________________\n",
      "lstm_1 (LSTM)                (None, 100)               80400     \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 10)                1010      \n",
      "=================================================================\n",
      "Total params: 5,081,410\n",
      "Trainable params: 5,081,410\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "#定义模型\n",
    "model = Sequential()\n",
    "model.add(Embedding(MAX_NB_WORDS, EMBEDDING_DIM, input_length=X.shape[1]))\n",
    "model.add(SpatialDropout1D(0.2))\n",
    "model.add(LSTM(100, dropout=0.2, recurrent_dropout=0.2))\n",
    "model.add(Dense(10, activation='softmax'))\n",
    "model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])\n",
    "print(model.summary())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 50845 samples, validate on 5650 samples\n",
      "Epoch 1/5\n",
      "50845/50845 [==============================] - 444s 9ms/step - loss: 0.7750 - acc: 0.7390 - val_loss: 0.3645 - val_acc: 0.8791\n",
      "Epoch 2/5\n",
      "50845/50845 [==============================] - 440s 9ms/step - loss: 0.2987 - acc: 0.9020 - val_loss: 0.3266 - val_acc: 0.8899\n",
      "Epoch 3/5\n",
      "50845/50845 [==============================] - 441s 9ms/step - loss: 0.2120 - acc: 0.9287 - val_loss: 0.3237 - val_acc: 0.8931\n",
      "Epoch 4/5\n",
      "50845/50845 [==============================] - 440s 9ms/step - loss: 0.1692 - acc: 0.9429 - val_loss: 0.3600 - val_acc: 0.8892\n",
      "Epoch 5/5\n",
      "50845/50845 [==============================] - 441s 9ms/step - loss: 0.1473 - acc: 0.9500 - val_loss: 0.3665 - val_acc: 0.8865\n"
     ]
    }
   ],
   "source": [
    "epochs = 5\n",
    "batch_size = 64\n",
    "\n",
    "history = model.fit(X_train, Y_train, epochs=epochs, batch_size=batch_size,validation_split=0.1,\n",
    "                    callbacks=[EarlyStopping(monitor='val_loss', patience=3, min_delta=0.0001)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6278/6278 [==============================] - 13s 2ms/step\n",
      "Test set\n",
      "  Loss: 0.353\n",
      "  Accuracy: 0.890\n"
     ]
    }
   ],
   "source": [
    "accr = model.evaluate(X_test,Y_test)\n",
    "print('Test set\\n  Loss: {:0.3f}\\n  Accuracy: {:0.3f}'.format(accr[0],accr[1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fcae029ce80>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.title('Loss')\n",
    "plt.plot(history.history['loss'], label='train')\n",
    "plt.plot(history.history['val_loss'], label='test')\n",
    "plt.legend()\n",
    "plt.show();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fcae02f51d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.title('Accuracy')\n",
    "plt.plot(history.history['acc'], label='train')\n",
    "plt.plot(history.history['val_acc'], label='test')\n",
    "plt.legend()\n",
    "plt.show();"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# LSTM模型的评估 \n",
    "\n",
    "接下来我们通过画混淆矩阵和求F1分数来评估我们模型的表现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred = model.predict(X_test)\n",
    "y_pred = y_pred.argmax(axis = 1)\n",
    "Y_test = Y_test.argmax(axis = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5,51.2344,'预测结果')"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fcae02facf8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import seaborn as sns\n",
    "from sklearn.metrics import accuracy_score, confusion_matrix\n",
    "#生成混淆矩阵\n",
    "conf_mat = confusion_matrix(Y_test, y_pred)\n",
    "fig, ax = plt.subplots(figsize=(10,8))\n",
    "sns.heatmap(conf_mat, annot=True, fmt='d',\n",
    "            xticklabels=cat_id_df.cat.values, yticklabels=cat_id_df.cat.values)\n",
    "plt.ylabel('实际结果',fontsize=18)\n",
    "plt.xlabel('预测结果',fontsize=18)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "accuracy 0.8897738133163428\n",
      "             precision    recall  f1-score   support\n",
      "\n",
      "         书籍       0.97      0.93      0.95       373\n",
      "         平板       0.78      0.82      0.80       998\n",
      "         手机       0.87      0.82      0.84       250\n",
      "         水果       0.94      0.90      0.92       965\n",
      "        洗发水       0.82      0.83      0.83      1006\n",
      "        热水器       0.88      0.54      0.67        54\n",
      "         蒙牛       1.00      1.00      1.00       204\n",
      "         衣服       0.86      0.91      0.89       992\n",
      "        计算机       0.93      0.90      0.91       400\n",
      "         酒店       0.99      0.97      0.98      1036\n",
      "\n",
      "avg / total       0.89      0.89      0.89      6278\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from  sklearn.metrics import classification_report\n",
    " \n",
    "print('accuracy %s' % accuracy_score(y_pred, Y_test))\n",
    "print(classification_report(Y_test, y_pred,target_names=cat_id_df['cat'].values))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 自定义预测\n",
    "\n",
    "首先我们定义一个预测函数:通过输入一段评语,来预测它的类目"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [],
   "source": [
    "def predict(text):\n",
    "    txt = remove_punctuation(text)\n",
    "    txt = [\" \".join([w for w in list(jb.cut(txt)) if w not in stopwords])]\n",
    "    seq = tokenizer.texts_to_sequences(txt)\n",
    "    padded = pad_sequences(seq, maxlen=MAX_SEQUENCE_LENGTH)\n",
    "    pred = model.predict(padded)\n",
    "    cat_id= pred.argmax(axis=1)[0]\n",
    "    return cat_id_df[cat_id_df.cat_id==cat_id]['cat'].values[0]\n",
    "      "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'水果'"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict('苹果好吃又不贵，已经买了很多次了')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'平板'"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict('收到产品已经半个多月了，一开始用着不太好用，慢慢的就好使了，可能是习惯问题吧，主要是屏的分辨率真的不错。')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'书籍'"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict('可能中外文化理解差异，可能与小孩子太有代沟，不觉得怎么样，还是比较喜欢水墨画一点风格的漫画书，但愿我女儿长大一点能喜欢（22个月中）')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'洗发水'"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict('假的，不好用，头皮痒的要命。。。')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'酒店'"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict('这是第三次点评，纯粹是为了拿积分。没什么可以多说了，服务不错。')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'酒店'"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#自定义review\n",
    "predict('房间挺大，就是价格贵了点')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'水果'"
      ]
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#自定义review\n",
    "predict('酸的要死，下次不买了')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'水果'"
      ]
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#自定义review\n",
    "predict('酸的要死，下次不买了')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'平板'"
      ]
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#自定义review\n",
    "predict('用了几天就好卡，上当了，退款')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'洗发水'"
      ]
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#自定义review\n",
    "predict('用了几次发现头好痒，感觉过敏了')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'手机'"
      ]
     },
     "execution_count": 98,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict('手写识别还可以')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'衣服'"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict('T恤很好看，就是短了点')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
